package com.sky.chapter3.lock;

import java.sql.Time;
import java.util.Date;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author : wushikai
 * <p>
 * date : 2022-07-04
 * <p>
 * 使用乐观锁 CAS  代替  synchronized ;
 * synchronized是悲观锁，这种线程一旦得到锁，其他需要锁的线程就挂起的情况就是悲观锁。
 * CAS操作的就是乐观锁，每次不加锁而是假设没有冲突而去完成某项操作，如果因为冲突失败就重试，直到成功为止。
 *
 * todo 多个线程还不好统计, 可以使用  CompletableFuture 来 改造;
 *
 * Synchronized虽然确保了线程的安全，但是在性能上却不是最优的，Synchronized关键字会让没有得到锁资源的线程进入BLOCKED状态，
 * 而后在争夺到锁资源后恢复为RUNNABLE状态，这个过程中涉及到操作系统用户模式和内核模式的转换，代价比较高。
 *
 * 尽管Java1.6为Synchronized做了优化，增加了从偏向锁到轻量级锁再到重量级锁的过度，但是在最终转变为重量级锁之后，性能仍然较低。
 *
 * 所谓原子操作类，指的是 java.util.concurrent.atomic包下，一系列以Atomic开头的包装类。例如AtomicBoolean，AtomicInteger，
 * AtomicLong。它们分别用于Boolean，Integer，Long类型的原子性操作。
 *
 *
 */
public class SynchronizedDemo5 {




    private static AtomicInteger atomicInteger = new AtomicInteger(0);

    private static      Integer integer = 0 ;

    private static void runCAS() {



        for (int i = 0; i < 4; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {

                    //每个线程让count自增10000次
                    for (int i = 0; i < 10000; i++) {
                        atomicInteger.incrementAndGet();
                    }
                    System.out.println("cas 子线程结束");
                }
            }).start();
        }




    }


    private static synchronized  void setInteger() {
        SynchronizedDemo5.integer =   integer + 1;
    }

    private static void runSynchronize(){

        for (int i = 0; i < 4; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {

                    //每个线程让count自增10000次
                    for (int i = 0; i < 10000; i++) {
                        setInteger();
                    }
                    System.out.println("runSynchronize 子线程结束");
                }
            }).start();
        }


    }



    public static void main(String[] args) {



        runSynchronize();
        runCAS();
        try {
            Thread.sleep(2000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println( integer);
        System.out.println(atomicInteger);


    }


}
